const WebSocket = require('ws');
const http = require('http');

class TogetherWatchServer {
    constructor(port = 8080) {
        // 房间存储
        this.rooms = new Map();

        // 创建HTTP服务器
        this.server = http.createServer();

        // 创建WebSocket服务器
        this.wss = new WebSocket.Server({
            server: this.server
        });

        // 监听WebSocket连接
        this.wss.on('connection', (ws) => {
            console.log('新的客户端连接');

            // 监听消息
            ws.on('message', (message) => {
                try {
                    const data = JSON.parse(message);
                    this.handleMessage(ws, data);
                } catch (error) {
                    console.error('解析消息错误:', error);
                }
            });

            // 处理连接关闭
            ws.on('close', () => {
                this.handleDisconnect(ws);
            });
        });

        // 启动服务器
        this.server.listen(port, () => {
            console.log(`TogetherWatch服务器运行在 ws://localhost:${port}`);
        });
    }

    // 处理不同类型的消息
    handleMessage(ws, data) {
        switch (data.type) {
            case 'create_room':
                this.createRoom(ws, data.roomId);
                break;
            case 'join_room':
                this.joinRoom(ws, data.roomId);
                break;
            case 'sync_video':
                this.broadcastToRoom(data.roomId, data, ws);
                break;
            case 'request_video_status':
                this.handleVideoStatusRequest(ws, data.roomId);
                break;
        }
    }

    // 创建房间
    createRoom(ws, roomId) {
        // 检查房间是否已存在
        if (this.rooms.has(roomId)) {
            ws.send(JSON.stringify({
                type: 'error',
                message: '房间已存在'
            }));
            return;
        }

        // 创建新房间
        this.rooms.set(roomId, {
            host: ws,
            members: new Set(),
            currentVideoInfo: null
        });

        // 通知房主房间创建成功
        ws.send(JSON.stringify({
            type: 'room_joined',
            roomId: roomId
        }));

        console.log(`创建房间：${roomId}`);
    }

    // 加入房间
    joinRoom(ws, roomId) {
        const room = this.rooms.get(roomId);

        // 检查房间是否存在
        if (!room) {
            ws.send(JSON.stringify({
                type: 'error',
                message: '房间不存在'
            }));
            return;
        }

        // 添加成员
        room.members.add(ws);

        // 通知成员加入成功
        ws.send(JSON.stringify({
            type: 'room_joined',
            roomId: roomId
        }));

        // 如果有当前视频信息，发送给新成员
        if (room.currentVideoInfo) {
            ws.send(JSON.stringify({
                type: 'current_video_status',
                videoInfo: room.currentVideoInfo
            }));
        }

        console.log(`成员加入房间：${roomId}`);
    }

    // 广播消息到房间
    broadcastToRoom(roomId, data, sender) {
        const room = this.rooms.get(roomId);
        if (!room) return;

        // 更新当前视频信息（由房主发送）
        if (sender === room.host) {
            room.currentVideoInfo = data.videoInfo;
        }

        // 广播给所有成员（除发送者）
        const broadcastData = JSON.stringify(data);

        // 广播给房主
        if (room.host && room.host !== sender) {
            try {
                room.host.send(broadcastData);
            } catch (error) {
                console.error('向房主广播失败:', error);
            }
        }

        // 广播给其他成员
        room.members.forEach((member) => {
            if (member !== sender) {
                try {
                    member.send(broadcastData);
                } catch (error) {
                    console.error('向成员广播失败:', error);
                    room.members.delete(member);
                }
            }
        });
    }

    // 处理视频状态请求
    handleVideoStatusRequest(ws, roomId) {
        const room = this.rooms.get(roomId);
        if (!room || !room.currentVideoInfo) return;

        // 请求当前视频状态
        room.host.send(JSON.stringify({
            type: 'request_video_status',
            roomId: roomId
        }));
    }

    // 处理断开连接
    handleDisconnect(ws) {
        // 遍历所有房间
        for (const [roomId, room] of this.rooms.entries()) {
            // 如果是房主断开
            if (ws === room.host) {
                console.log(`房间 ${roomId} 的房主已断开`);

                // 通知所有成员
                room.members.forEach((member) => {
                    try {
                        member.send(JSON.stringify({
                            type: 'error',
                            message: '房主已离开房间'
                        }));
                    } catch (error) {
                        console.error('发送断开通知失败:', error);
                    }
                });

                // 删除房间
                this.rooms.delete(roomId);
            } else {
                // 如果是成员断开
                room.members.delete(ws);
            }
        }
    }
}

// 启动服务器
const togetherWatchServer = new TogetherWatchServer(8080);

module.exports = TogetherWatchServer;